package com.mybatisplus.job;

import com.mybatisplus.entity.QuartzJob;
import com.mybatisplus.entity.QuartzLog;
import com.mybatisplus.job.threadPool.ThreadPoolExecutorUtil;
import com.mybatisplus.mapper.QuartzJobMapper;
import com.mybatisplus.mapper.QuartzLogMapper;
import org.quartz.JobExecutionContext;
import org.quartz.JobKey;
import org.quartz.Scheduler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.quartz.QuartzJobBean;

import javax.annotation.Resource;
import java.util.concurrent.Future;
import java.util.concurrent.ThreadPoolExecutor;

@Async
public class ExecutionJob extends QuartzJobBean {

    private Logger logger = LoggerFactory.getLogger(this.getClass());

    private static final String JOB_NAME = "TASK_";

    @Resource(name = "scheduler")
    private Scheduler scheduler;

    /** 该处仅供参考 */
    private final static ThreadPoolExecutor EXECUTOR = ThreadPoolExecutorUtil.getPoll();


    @Override
    @SuppressWarnings("unchecked")
    protected void executeInternal(JobExecutionContext context) {
        QuartzJob quartzJob = (QuartzJob) context.getMergedJobDataMap().get(QuartzJob.JOB_KEY);
        // 获取spring bean
        QuartzJobMapper quartzJobMapper = SpringContextHolder.getBean(QuartzJobMapper.class);
        QuartzLogMapper quartzLogMapper = SpringContextHolder.getBean(QuartzLogMapper.class);

        QuartzLog log = new QuartzLog();
        log.setJobName(quartzJob.getJobName());

        log.setBaenName(quartzJob.getBeanName());
        log.setMethodName("run");
        log.setParams(quartzJob.getParams());
        long startTime = System.currentTimeMillis();
        log.setCronExpression(quartzJob.getCronExpression());
        try {
            // 执行任务
            logger.info("任务准备执行，任务名称：{}", quartzJob.getJobName());
            QuartzRunnable task = new QuartzRunnable(quartzJob.getBeanName(), quartzJob.getMethodName(),quartzJob.getParams());
            Future<?> future = EXECUTOR.submit(task);
            future.get();
            long times = System.currentTimeMillis() - startTime;
            log.setTime(times);
            // 任务状态
            log.setIsSuccess(1);
            log.setExceptionDetail("执行成功");
            logger.info("任务执行完毕，任务名称：{} 总共耗时：{} 毫秒", quartzJob.getJobName(), times);
        }  catch (Exception e) {
            logger.info("任务执行失败，失败原因{}",e.getMessage());
            long times = System.currentTimeMillis() - startTime;
            log.setTime(times);
            // 任务状态 1：成功 0：失败
            log.setIsSuccess(0);
            log.setExceptionDetail("定时执行失败");
            quartzJob.setIsPause(1);
            try {
                JobKey jobKey = JobKey.jobKey(JOB_NAME + quartzJob.getId());
                scheduler.pauseJob(jobKey);
            } catch (Exception ee){
                logger.info("定时任务暂停失败{}",ee.getMessage());
                throw new BadRequestException("定时任务暂停失败");
            }
            //更新状态
            quartzJobMapper.updateById(quartzJob);
        }  finally {
            quartzLogMapper.insert(log);
        }
    }
}
